package com.ling.sdk.live

import android.app.Activity
import android.content.Context
import android.os.Bundle
import android.util.Log
import com.ling.sdk.BuildConfig
import com.ling.sdk.app.ActivityStack
import com.ling.sdk.app.App
import com.ling.sdk.utils.WeakHandler
import com.ling.sdk.utils.WorkThreadFactory
import java.util.concurrent.CopyOnWriteArrayList

object LiveManager : LifecycleCallback() {

    private val handlerPool = HashMap<String, WeakHandler>()
    private val contextPool = HashMap<String, Context>().apply { put(ActivityStack.genSafeKey(App.app), App.app) }
    private val uiLives = HashMap<String, CopyOnWriteArrayList<ILiveUI>>()
    private val executors = HashMap<String, WorkThreadFactory>()


    //========================================messenger================================//
    fun handler(): WeakHandler {
        return handler(App.app)
    }

    fun handler(context: Context?): WeakHandler {
        return handler(ActivityStack.genSafeKey(context))
    }

    fun handler(token: String, isSelfFinished: Boolean = false): WeakHandler {
        if (contextPool.contains(token)) { // 如果act 被销毁  contextPool中的context 也会被移除，这时候如果获取handler 返回一个销毁状态的handler
            return handlerPool[token] ?: WeakHandler().apply { handlerPool[token] = this }
        }
        //是否自己管理， 如果是，记得销毁
        if (isSelfFinished) return WeakHandler().apply { handlerPool[token] = this }
        return WeakHandler().apply { setDestroy(true) }
    }


    fun sendMessage(tag: Any, context: Context?, data: Any) {
        liveLog("${tag.javaClass.simpleName}::sendMessage->$data")
        uiLives[ActivityStack.genKey(context)]?.forEach { it.receiverMessage(data) }
    }

    fun sendMessageAsync(tag: Any, context: Context?, data: Any) {
        liveLog("${tag.javaClass.simpleName}::sendMessage->$data")
        handler(context).post { uiLives[ActivityStack.genKey(context)]?.forEach { it.receiverMessage(data) } }
    }

    fun exec(context: Context?, runnable: () -> Unit) {
        exec(context, Runnable { runnable.invoke() })
    }

    fun exec(runnable: () -> Unit) {
        exec(App.app, Runnable { runnable.invoke() })
    }

    fun exec(context: Context?, runnable: Runnable) {
        val token = ActivityStack.genSafeKey(context)
        if (contextPool.contains(token)) {
            val executor = executors[token]
                    ?: WorkThreadFactory.createThreadPool(context?.javaClass?.simpleName, 1).apply { executors[token] = this }
            executor.execute(runnable)
        }
    }


    //=============================set up ==========================================//
    private fun setUpContext(token: String, context: Context) = contextPool.put(token, context)

    fun getContext(token: String) = contextPool[token]

    fun addLiveUI(context: Context?, liveUI: ILiveUI?) {
        context ?: return // 如果context 为空的 不能添加 不能因为他是空的就把它添加到app-context
        liveUI ?: return
        val token = ActivityStack.genSafeKey(context)
        val list = uiLives[token] ?: CopyOnWriteArrayList()
        uiLives[token] = list
        if (!list.contains(liveUI)) {
            list.add(liveUI)
            if (liveUI is ILiveUIChild) {
                liveUI.onAttachLive(token)
            }
        }
    }


    //=================================dispatch=====================================//

    override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
        activity?.also { ActivityStack.genSafeKey(it).also { setUpContext(it, activity) } }

        if (activity is ILiveUI) addLiveUI(activity, activity)
    }

    override fun onActivityResumed(activity: Activity?) {
        activity?.also { uiLives[ActivityStack.genKey(activity)]?.forEach { it.onActivityResume() } }
    }

    override fun onActivityPaused(activity: Activity?) {
        activity?.also { uiLives[ActivityStack.genKey(activity)]?.forEach { it.onActivityPause() } }
    }

    override fun onActivityStopped(activity: Activity?) {
        activity?.also { uiLives[ActivityStack.genKey(activity)]?.forEach { it.onActivityStop() } }
    }

    fun dispatchNetworkChange(token: String?, isConnected: Boolean, netType: Int) {
        token ?: return
        uiLives[token]?.forEach { it.onNetworkChange(isConnected, netType) }
    }


    ///============================clear up ================================================//


    fun onActivityFinish(activity: Activity) {
        uiLives[ActivityStack.genKey(activity)]?.forEach { it.onActivityFinish() }
        uiLives[ActivityStack.genKey(activity)]?.forEach { it.onCleanUp() }

        activity.also {
            val token = ActivityStack.genSafeKey(it)
            clearHandler(it)
            clearExecutors(it)
            uiLives.remove(token)
            clearContext(token)
        }
    }


    fun removeLiveUI(context: Context?, liveUI: ILiveUI?) {
        context ?: return
        liveUI ?: return
        uiLives[ActivityStack.genKey(context)]?.remove(liveUI)
    }

    private fun clearHandler(context: Context?) {
        context ?: return
        val token = ActivityStack.genKey(context)
        handlerPool[token]?.removeCallbacksAndMessages(null)
        handlerPool.remove(token)
    }

    private fun clearExecutors(context: Context?) {
        context ?: return
        val token = ActivityStack.genKey(context)
        executors[token]?.shutdownNow()
        executors.remove(token)
    }

    private fun clearContext(token: String) = contextPool.remove(token)

    //================================log===================================//

    fun liveLog(log: String) {
        if (BuildConfig.DEBUG)
            Log.e("LiveManger", log)
    }

/*
    fun onActivityBackPress(activity: Activity): Boolean {
        val list = uiLives[ActivityStack.genKey(activity)] ?: return true
        list.reversed().forEach {
            val isBack = it.onActivityBackPress()
            if (isBack) return true
        }
        return true
    }*/

}